/*
 * Copyright (c) United Binary LLC.  All rights reserved.
 * 
 * This code is licensed under the MIT License
 * 
 * SEE: http://harnessit.codeplex.com/license
 * 
 */
using System;

namespace UnitedBinary.Core.Application.Configuration.CommandLine
{
	/// <include file='CommandLine.xml' path='/Docs/CommandLineString/Class/*'/>
	public class CommandLineString
	{
		private struct OptionValuePair
		{
			internal string option;
			internal string val;
		};

		private string cmdLine = string.Empty;
		private OptionValuePair[] pairs;

		/// <include file='CommandLine.xml' path='/Docs/CommandLineString/ctor/*'/>
		public CommandLineString()
		{
		}

		/// <include file='CommandLine.xml' path='/Docs/CommandLineString/CommandLineProp/*'/>
		public string CommandLine
		{
			set
			{
				cmdLine = value;
				ParseCommandLine();
			}
			get
			{
				return cmdLine;
			}
		}

		private bool AddPair(OptionValuePair pair)
		{
			if (pair.option == null || pair.option.Length == 0)
			{
				return false;
			}

			foreach (OptionValuePair p in pairs)
			{
				if (p.option == pair.option)
				{
					return true;
				}
			}

			OptionValuePair[] tempPairs = new OptionValuePair [pairs.Length+1];
			for (int i=0; i < pairs.Length; i++)
			{
				tempPairs[i] = pairs[i];
			}
			tempPairs[pairs.Length] = pair;

			pairs = tempPairs;
			return true;
		}

		/// <include file='CommandLine.xml' path='/Docs/CommandLineString/GetValue/*'/>
		public string GetValue(string option)
		{
			return GetValue(option, false);
		}

		/// <include file='CommandLine.xml' path='/Docs/CommandLineString/GetValue_case/*'/>
		public string GetValue(string option, bool ignoreCase)
		{
			string existingOption = string.Empty;
			string targetOption = option.Trim(new char[] {' ', '\"'});

			if (ignoreCase)
			{
				targetOption = targetOption.ToLower();
			}

			foreach (OptionValuePair p in pairs)
			{
				existingOption = p.option;
				if (ignoreCase)
				{
					existingOption = existingOption.ToLower();
				}

				if (existingOption == targetOption)
				{
					return p.val;
				}
			}

			ArgumentException e = new ArgumentException("Option \"" + option + "\" not found.", "option");
			throw e;
		}

		/// <include file='CommandLine.xml' path='/Docs/CommandLineString/ContainsValue/*'/>
		public bool ContainsValue(string option)
		{
			return ContainsValue(option, false);
		}

		/// <include file='CommandLine.xml' path='/Docs/CommandLineString/ContainsValue_case/*'/>
		public bool ContainsValue(string option, bool ignoreCase)
		{
			string existingOption = string.Empty;
			string targetOption = option;
			if (ignoreCase)
			{
				targetOption = targetOption.ToLower();
			}

			foreach (OptionValuePair p in pairs)
			{
				existingOption = p.option;
				if (ignoreCase)
				{
					existingOption = existingOption.ToLower();
				}

				if (existingOption == targetOption)
				{
					return true;
				}
			}
			return false;
		}

		/// <include file='CommandLine.xml' path='/Docs/CommandLineString/Length/*'/>
		public int Length
		{
			get
			{
				return cmdLine.Length;
			}
		}

		private void ParseCommandLine()
		{
			pairs = new OptionValuePair [0];
			char[] delims = {'/'};

			if (cmdLine == null || cmdLine.Length == 0)
			{
				return;
			}

			string[] textpairs = cmdLine.Split(delims);

			delims[0] = '=';
			foreach (string s in textpairs)
			{
				string[] textpair = s.Split(delims);
				if (textpair.Length == 2)
				{
					OptionValuePair np = new OptionValuePair();

					np.option = textpair[0].Trim(new char[] {' ', '\"'});
					np.val = textpair[1].Trim(new char[] {' ', '\"'});

					AddPair(np);
				}
			}
		}
	}

}
